package ch.nostromo.tiffanys.game.game;

import java.util.ArrayList;
import java.util.Arrays;

import ch.nostromo.tiffanys.game.board.Board;
import ch.nostromo.tiffanys.game.board.BoardException;
import ch.nostromo.tiffanys.game.chess.Chess;
import ch.nostromo.tiffanys.game.chess.ChessException;

public class GameTools {

  
  public static GameState getCurrentGameState(ArrayList<Board> history_boards, Board board, int colorToMove) throws ChessException, BoardException  {

    if (isMate(board, colorToMove)) {
      if (colorToMove == Game.COLOR_WHITE) {
        return new GameState(GameState.STATE_BLACK_MATES);
      } else {
        return new GameState(GameState.STATE_WHITE_MATES);
      }
    }

    if (isMaterialRemis(board)) {
      return new GameState(GameState.STATE_REMIS_BY_MATERIAL);
    }
    if (isFiftyRemis(board, history_boards)) {
      return new GameState(GameState.STATE_REMIS_BY_FIFTY);
    }
    if (isThreeRemis(history_boards)) {
      return new GameState(GameState.STATE_REMIS_BY_THREE);
    }
    if (isStaleMate(board, colorToMove)) {
      return new GameState(GameState.STATE_REMIS_BY_STALE_MATE);
    }
    if (isInCheck(board, colorToMove)) {
      if (colorToMove == Game.COLOR_WHITE) {
        return new GameState(GameState.STATE_BLACK_CHECKS);
      } else {
        return new GameState(GameState.STATE_WHITE_CHECKS);
      }
    }
    
    return new GameState(GameState.STATE_GAME_OPEN);

  }

  public static boolean isInCheck(Board board, int colorToMove) throws BoardException {
      return Chess.isInCheck(board, colorToMove);
  }
  
  public static boolean isMate(Board board, int colorToMove) throws ChessException, BoardException {
      return Chess.isMate(board, colorToMove);
  }

  private static boolean isStaleMate(Board board, int colorToMove) throws  ChessException, BoardException {
      return Chess.isStaleMate(board, colorToMove);
  }

  private static boolean isMaterialRemis(Board board) {
    return Chess.isMaterialRemis(board);
  }
  
  private static boolean isFiftyRemis(Board board, ArrayList<Board> history_boards) {
    int result = 0;
    int currentMaterial = board.getTotalMaterialCount();

    for (int i = history_boards.size() - 1; i > 0; i--) {
      int mat = history_boards.get(i).getTotalMaterialCount();
      if (mat == currentMaterial) {
        result++;
      } else {
        return (result > 50);
      }
    }
    return (result > 50);
  }
  
  private static boolean isThreeRemis(ArrayList<Board> history_boards) {
    if (history_boards.size() > 6) {
      int[] board1 = history_boards.get(history_boards.size() -1).getBoardArray();
      int[] board2 = history_boards.get(history_boards.size() -3).getBoardArray();
      int[] board3 = history_boards.get(history_boards.size() -5).getBoardArray();
      
      return (Arrays.equals(board1, board2) && Arrays.equals(board2, board3));
    } else {
      return false;
    }
  }
  

  public static int switchColor(int colorToMove) throws GameException {
    if (colorToMove == Game.COLOR_WHITE) {
      return Game.COLOR_BLACK;
    } else if (colorToMove == Game.COLOR_BLACK) {
      return Game.COLOR_WHITE;
    }
    
    throw new GameException("Unknown play color");
  }

  
}
